RoleRbac   A
last analyzed

Complexity

Total Complexity 24

Size/Duplication

Total Lines 85
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 24
eloc 65
dl 0
loc 85
rs 10
c 0
b 0
f 0

5 Functions

Rating   Name   Duplication   Size   Complexity  
A anyAsync 0 9 1
A any 0 11 1
A can 0 3 1
A canAsync 0 3 1
F checkPermissions 0 44 20
1
import { Injectable } from '@nestjs/common';
2
import { IRoleRbac } from './interfaces/role.rbac.interface';
3
import { IFilterPermission } from '../permissions/interfaces/filter.permission.interface';
4
import { IParamsFilter } from '../params-filter/interfaces/params.filter.interface';
5
6
@Injectable()
7
export class RoleRbac implements IRoleRbac {
8
    constructor(
9
        private readonly role: string,
10
        private readonly grant: string[],
11
        private readonly filters: object,
12
        private readonly paramsFilter?: IParamsFilter,
13
    ) {
14
    }
15
16
    canAsync(...permissions: string[]): Promise<boolean> {
17
        return this.checkPermissions<Promise<boolean>>(permissions, 'canAsync');
18
    }
19
20
    can(...permissions: string[]): boolean {
21
        return this.checkPermissions<boolean>(permissions, 'can');
22
    }
23
24
    any(...permissions: string[][]): boolean {
25
        // loop through the list of permission list
26
        return (
27
            permissions
28
                .map(permission => {
29
                    // check each of the permission list
30
                    return this.can(...permission);
31
                })
32
                // any permission list is true, then return true as result
33
                .some(result => result)
34
        );
35
    }
36
37
    async anyAsync(...permissions: string[][]): Promise<boolean> {
38
        return (
39
            await Promise.all(
40
                permissions.map(permission => {
41
                    return this.canAsync(...permission);
42
                }),
43
            )
44
        ).some(result => result);
45
    }
46
47
    private checkPermissions<T>(permissions, methodName): T {
48
        if (!permissions.length) {
49
            return false as any;
50
        }
51
        // check grant
52
        for (const permission of permissions) {
53
            if (!this.grant.includes(permission)) {
54
                return false as any;
55
            }
56
        }
57
58
        // check custom filter
59
        for (const permission of permissions) {
60
            // check particular permission [permission@action]
61
            if (this.grant.includes(permission) && permission.includes('@')) {
62
                const filter: string = permission.split('@')[1];
63
                const filterService: IFilterPermission = this.filters[filter];
64
                if (filterService) {
65
                    return (
66
                        filterService?.[methodName]?.(
67
                            this.paramsFilter ? this.paramsFilter.getParam(filter) : null,
68
                        ) ?? true
69
                    );
70
                }
71
            }
72
            // check particular permission [permission]
73
            if (this.grant.includes(permission) && !permission.includes('@')) {
74
                for (const filter in this.filters) {
75
                    if (
76
                        this.filters.hasOwnProperty(filter) &&
77
                        this.grant.includes(`${permission}@${filter}`)
78
                    ) {
79
                        return (
80
                            this.filters[filter]?.[methodName]?.(
81
                                this.paramsFilter ? this.paramsFilter.getParam(filter) : null,
82
                            ) ?? true
83
                        );
84
                    }
85
                }
86
            }
87
        }
88
89
        return true as any;
90
    }
91
}
92